package com.dawn.module.mp.service.msgtemplate;

import com.alibaba.fastjson.JSONObject;
import com.dawn.module.mp.dal.dataobject.account.MpAccountDO;
import com.dawn.module.mp.dal.dataobject.msgtemplatelog.MsgTemplateLogDO;
import com.dawn.module.mp.dal.mysql.msgtemplatelog.MsgTemplateLogMapper;
import com.dawn.module.mp.framework.mp.core.MpServiceFactory;
import com.dawn.module.mp.service.account.MpAccountService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplate;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import com.dawn.module.mp.controller.admin.msgtemplate.vo.*;
import com.dawn.module.mp.dal.dataobject.msgtemplate.MsgTemplateDO;
import com.dawn.framework.common.pojo.PageResult;
import com.dawn.framework.common.util.object.BeanUtils;

import com.dawn.module.mp.dal.mysql.msgtemplate.MsgTemplateMapper;

import javax.annotation.Resource;

import java.util.List;
import java.util.stream.Collectors;

import static com.dawn.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.dawn.module.mp.enums.ErrorCodeConstants.MSG_TEMPLATE_NOT_EXISTS;

/**
 * 模板消息 Service 实现类
 *
 * @author mamba 4 left
 */
@Service
@Validated
public class MsgTemplateServiceImpl implements MsgTemplateService {

    @Resource
    private MsgTemplateMapper msgTemplateMapper;

    @Resource
    @Lazy // 延迟加载，解决循环依赖的问题
    private MpServiceFactory mpServiceFactory;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private MpAccountService mpAccountService;

    @Resource
    private MsgTemplateLogMapper msgTemplateLogMapper;

    @Override
    public Long createMsgTemplate(MsgTemplateSaveReqVO createReqVO) {
        // 插入
        MsgTemplateDO msgTemplate = BeanUtils.toBean(createReqVO, MsgTemplateDO.class);
        msgTemplateMapper.insert(msgTemplate);
        // 返回
        return msgTemplate.getId();
    }

    @Override
    public void updateMsgTemplate(MsgTemplateSaveReqVO updateReqVO) {
        // 校验存在
        validateMsgTemplateExists(updateReqVO.getId());
        // 更新
        MsgTemplateDO updateObj = BeanUtils.toBean(updateReqVO, MsgTemplateDO.class);
        msgTemplateMapper.updateById(updateObj);
    }

    @Override
    public void deleteMsgTemplate(Long id) {
        // 校验存在
        validateMsgTemplateExists(id);
        // 删除
        msgTemplateMapper.deleteById(id);
    }

    private void validateMsgTemplateExists(Long id) {
        if (msgTemplateMapper.selectById(id) == null) {
            throw exception(MSG_TEMPLATE_NOT_EXISTS);
        }
    }

    @Override
    public MsgTemplateDO getMsgTemplate(Long id) {
        return msgTemplateMapper.selectById(id);
    }

    @Override
    public PageResult<MsgTemplateDO> getMsgTemplatePage(MsgTemplatePageReqVO pageReqVO) {
        return msgTemplateMapper.selectPage(pageReqVO);
    }

    @Override
    public void syncWxTemplate(Long accountId) {
        try {
            MpAccountDO mpAccount = mpAccountService.getRequiredAccount(accountId);
            WxMpService wxMpService = mpServiceFactory.getRequiredMpService(accountId);
            List<WxMpTemplate> wxMpTemplateList = wxMpService.getTemplateMsgService().getAllPrivateTemplate();
            List<MsgTemplateDO> templates = wxMpTemplateList.stream().map(item -> new MsgTemplateDO(item,mpAccount.getId(),mpAccount.getAppId())).collect(Collectors.toList());
            msgTemplateMapper.insertBatch(templates);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 发送微信模版消息,使用固定线程的线程池
     * @param msg
     * @param appid
     */
    @Override
    @Async
    public void sendTemplateMsg(WxMpTemplateMessage msg, String appid) {
        String result;
        Boolean status;
        try {
            WxMpService wxService = mpServiceFactory.getRequiredMpService(appid);
            wxService.switchover(appid);
            result = wxService.getTemplateMsgService().sendTemplateMsg(msg);
            status = Boolean.TRUE;
        } catch (WxErrorException e) {
            result = e.getMessage();
            status = Boolean.FALSE;
        }

        //保存发送日志
        MsgTemplateLogDO log = new MsgTemplateLogDO(msg,appid, result, status);
        MpAccountDO mpAccount = mpAccountService.getAccountFromCache(appid);
        log.setAccountId(mpAccount.getId());
        msgTemplateLogMapper.insert(log);
    }

    /**
     * 重复发送微信模版消息
     * @param msgLog
     */
    @Override
    @Async
    public void repeteSendTemplateMsg(MsgTemplateLogDO msgLog) {
        String result;
        Boolean status;
        try {
            WxMpService wxService = mpServiceFactory.getRequiredMpService(msgLog.getAppid());
            WxMpTemplateMessage msg = JSONObject.parseObject(msgLog.getMessage(), WxMpTemplateMessage.class);
            result = wxService.getTemplateMsgService().sendTemplateMsg(msg);
            status = Boolean.TRUE;
        } catch (WxErrorException e) {
            result = e.getMessage();
            status = Boolean.FALSE;
        }

        //修改发送日志状态
        msgLog.setSendResult(result);
        msgLog.setStatus(status);
        msgTemplateLogMapper.updateById(msgLog);
    }

}
